package util.bio.seq;
import util.gen.*;
import util.bio.parsers.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;

/**Merges many fasta's into one fasta with a defined number of X spacers.*/
public class MergeFastas {

	//fields
	private File[] fastaFiles;
	private File directory;
	private int numberXs = 0;
	private String spacer = "";
	private Fasta[] fastas;
	private String chromName;

	public MergeFastas (String[] args){
		//set chrom name
		chromName= args[2];
		
		//make files
		directory = new File (args[0]);
		File merged = new File(directory,chromName+".fasta");
		if (merged.exists()) merged.delete();
		File bed = new File(directory,chromName+".bed");
		if (bed.exists()) bed.delete();
		File bounds = new File(directory,chromName+"_bounds.bed");
		if (bounds.exists()) bounds.delete();
		
		//fetch files
		fastaFiles = IO.fetchFilesRecursively(directory, "fasta");
		
		//make spacer
		numberXs = Integer.parseInt(args[1]);
		char[] x = new char[numberXs];
		Arrays.fill(x, 'X');
		spacer = new String(x);

		//load fastas and sort by last number in name
		fastas = new MultiFastaParser(fastaFiles).getFastas();
		Arrays.sort(fastas);

		//print merged fasta to file and stats to screen
		//also print a bed file of regions
		try {
			PrintWriter out = new PrintWriter (new FileWriter ( merged));
			PrintWriter outBed = new PrintWriter (new FileWriter ( bed));
			PrintWriter outBounds = new PrintWriter (new FileWriter ( bounds));
			int cumLength = 0;
			//print first seq
			out.println(">"+chromName);
			out.println(fastas[0].getSeq());
			//print to screen
			System.out.println(fastas[0].getName()+"\t0");
			//print bed
			int newCumLength = fastas[0].getSeq().length();
			outBed.println(chromName+"\t"+cumLength+"\t"+newCumLength+"\t"+fastas[0].getName());
			cumLength = newCumLength+ numberXs;
			//print bounds bed
			outBounds.println(chromName+"\t"+newCumLength+"\t"+cumLength);
			//for each subsequent fasta
			for (int i=1; i< fastas.length; i++){
				//print to file
				out.println(spacer);
				out.println(fastas[i].getSeq());
				//print to screen
				System.out.println(fastas[i].getName()+"\t"+cumLength);
				//print to bed and set cumLength
				newCumLength = fastas[i].getSeq().length() + cumLength;
				outBed.println(chromName+"\t"+cumLength+"\t"+newCumLength +"\t"+fastas[i].getName());
				cumLength = newCumLength + numberXs;
				//print bounds bed
				outBounds.println(chromName+"\t"+newCumLength+"\t"+cumLength);
			}
			out.close();
			outBed.close();
			outBounds.close();
		} catch (Exception e){
			e.printStackTrace();
		}

	}




	public static void main(String[] args) {
		if (args.length ==0) Misc.printExit("\nEnter a directory containing xxx.fasta files for merging, " +
		"the number of X's to use as a spacer between each, and a name for the merged sequence. Note, interbase coordinates.\n");
		new MergeFastas(args);

	}

}
